package net.tv90.appserveradmin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import net.tv90.appserveradmin.dao.CheckitemMapper;
import net.tv90.appserveradmin.dao.SetmealDetailedMapper;
import net.tv90.appserveradmin.dao.SetmealMapper;
import net.tv90.appserveradmin.model.Checkitem;
import net.tv90.appserveradmin.model.Setmeal;
import net.tv90.appserveradmin.model.SetmealDetailed;
import net.tv90.appserveradmin.model.dto.CheckitemDTO;
import net.tv90.appserveradmin.model.dto.SetmealAddDTO;
import net.tv90.appserveradmin.model.dto.SetmealDTO;
import net.tv90.appserveradmin.model.vo.SetmealVO;
import net.tv90.appserveradmin.service.SetmealService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

@Service
public class SetmealServiceImpl implements SetmealService {
    @Autowired
    private SetmealMapper setmealMapper;

    @Autowired
    private SetmealDetailedMapper setmealdetailedMapper;

    @Autowired
    private CheckitemMapper checkitemMapper;

    @Override
    public List<SetmealVO> listAllSetmealsWithCheckitemNames() {
        List<Setmeal> setmeals = setmealMapper.selectList(null);
        return setmeals.stream().map(setmeal -> {
            SetmealVO setmealVO = new SetmealVO();
            setmealVO.setSmId(setmeal.getSmId());
            setmealVO.setName(setmeal.getName());
            setmealVO.setType(setmeal.getType());
            setmealVO.setPrice(setmeal.getPrice());
            List<SetmealDetailed> details = getSetmealDetails(setmeal.getSmId());
            List<String> checkitemNames = details.stream().map(detail -> {
                Checkitem checkitem = checkitemMapper.selectById(detail.getCiId());
                return checkitem.getCiName();
            }).collect(Collectors.toList());
            setmealVO.setCheckitemNames(checkitemNames);
            return setmealVO;
        }).collect(Collectors.toList());
    }

    @Override
    public List<Checkitem> getAllCheckitems() {
        return checkitemMapper.selectList(null);
    }

    @Transactional
    @Override
    public void addSetmeal(SetmealAddDTO setmealAddDTO) {
        Setmeal setmeal = new Setmeal();
        setmeal.setName(setmealAddDTO.getName());
        setmeal.setType(setmealAddDTO.getType());
        setmeal.setPrice(setmealAddDTO.getPrice());
        setmealMapper.insert(setmeal);
        List<SetmealDetailed> details = setmealAddDTO.getCheckitemIds().stream()
                .map(ciId -> {
                    SetmealDetailed detail = new SetmealDetailed();
                    detail.setSmId(setmeal.getSmId());
                    detail.setCiId(ciId);
                    return detail;
                })
                .toList();
        details.forEach(setmealdetailedMapper::insert);
    }

    @Transactional
    @Override
    public void updateSetmeal(SetmealAddDTO setmealAddDTO) {
        Setmeal setmeal = new Setmeal();
        setmeal.setSmId(setmealAddDTO.getSmId());
        setmeal.setName(setmealAddDTO.getName());
        setmeal.setType(setmealAddDTO.getType());
        setmeal.setPrice(setmealAddDTO.getPrice());
        setmealMapper.updateById(setmeal);
        QueryWrapper<SetmealDetailed> deleteWrapper = new QueryWrapper<>();
        deleteWrapper.eq("smId", setmeal.getSmId());
        setmealdetailedMapper.delete(deleteWrapper);
        List<SetmealDetailed> details = setmealAddDTO.getCheckitemIds().stream()
                .map(ciId -> {
                    SetmealDetailed detail = new SetmealDetailed();
                    detail.setSmId(setmeal.getSmId());
                    detail.setCiId(ciId);
                    return detail;
                })
                .toList();

        details.forEach(setmealdetailedMapper::insert);
    }

    @Transactional
    @Override
    public void deleteSetmeal(Integer smId) {
        setmealMapper.deleteById(smId);
        QueryWrapper<SetmealDetailed> deleteWrapper = new QueryWrapper<>();
        deleteWrapper.eq("smId", smId);
        setmealdetailedMapper.delete(deleteWrapper);
    }

    @Override
    public Setmeal getSetmealById(Integer smId) {
        return setmealMapper.selectById(smId);
    }

    @Override
    public List<SetmealDetailed> getSetmealDetails(Integer smId) {
        QueryWrapper<SetmealDetailed> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("smId", smId);
        return setmealdetailedMapper.selectList(queryWrapper);
    }

    @Override
    public SetmealDTO viewSetmeals(Long id) {
        Setmeal setmeal = setmealMapper.selectById(id);
        if (setmeal == null) {
            return null;
        }
        List<SetmealDetailed> details = getSetmealDetails(setmeal.getSmId());
        List<CheckitemDTO> checkitemDTOs = details.stream().map(detail -> {
            Checkitem checkitem = checkitemMapper.selectById(detail.getCiId());
            CheckitemDTO checkitemDTO = new CheckitemDTO();
            checkitemDTO.setCheckitem(checkitem);
            checkitemDTO.setCheckitemDetailed(null);
            return checkitemDTO;
        }).collect(Collectors.toList());
        return SetmealDTO.builder()
                .smId(setmeal.getSmId())
                .name(setmeal.getName())
                .type(setmeal.getType())
                .price(setmeal.getPrice())
                .checkitems(checkitemDTOs)
                .build();
    }

}
